//{
//! @file    SolveSquare.cpp
//! @date    2014-09-18
//! @author  Artem Mikhalev <grozzmaster@gmail.com>
//!
//! Solution of square equation.
//! User should input three coefficients of square equation a, b, c.
//}

#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <float.h>

#ifdef MY_COMPUTER
    #define DBG printf ("# ");
#else
    #define DBG if (0)
#endif

//{
//! The function 'solve_square' return '-1' if the square has infinite roots.
//}

const int INFINITE_ROOTS = -1;

int solve_square (double a, double b, double c,
                 double *x1, double *x2);

int main()
{
    DBG printf ("-----------------------------------------\n");
    DBG printf ("Solving square equation\n");
    DBG printf ("SolveSquare v.1.0 " __DATE__ " " __TIME__ "\n");
    DBG printf ("Input 3 coefficients of square equation\n");

    double a = 0, b = 0, c = 0;

    int ok = (scanf ("%lg %lg %lg", &a, &b, &c) == 3);
    if (!ok)
    {
        printf ("ERROR. Bad input. Example: 1 6 9\n");
        return 1;
    }

    double x1 = 0, x2 = 0;

    int nRoots = solve_square (a, b, c, &x1, &x2);

    switch (nRoots)
    {
        case INFINITE_ROOTS:
            printf ("number of roots:\n"
                    "infinity\n");
            printf ("roots:\n"
                    "infinite roots\n");
            break;

        case 0:
            printf ("number of roots:\n"
                    "0\n");
            printf ("roots:\n"
                    "no roots\n");
            break;

        case 1:
            printf ("number of roots:\n"
                    "1\n");
            printf ("root:\n"
                    "x = %lg\n", x1);
            break;

        case 2:
            printf ("number of roots:\n"
                    "2\n");
            printf ("roots:\n"
                    "x1 = %lg  x2 = %lg\n", x1, x2);
            break;

        default:
            printf ("ERROR. Incorrect returning value of function 'solve_square': %d\n", solve_square);
            break;
    }

    DBG printf ("-----------------------------------------\n");

    return 0;
}

//{
//! solve_square - solving an equation specified by its coefficients.
//!
//! @param      a   1st-coefficient
//! @param      b   2nd-coefficient
//! @param      c   3rd-coefficient
//! @param[out] x1  1st root of equation
//! @param[out] x2  2nd root of equation
//!
//! @return         Number of roots, -1 if infinite number of roots
//}

int solve_square (double a, double b, double c,
                  double *x1, double *x2)
{
    assert (x1 && x2);

    if (fabs (a) <= DBL_EPSILON)
    {
        if (fabs (b) <= DBL_EPSILON)
        {
            if (fabs (c) <= DBL_EPSILON)
                return INFINITE_ROOTS;
            else // c a == 0 b == 0 c != 0
                return 0;
        }

        else // a == 0 b != 0
        {
            *x1 = -c/b;
            return 1;
        }
    }

    else // a != 0
    {
        double d = b*b - 4*a*c;

        if (d < -DBL_EPSILON)
            return 0;
        else // d >= 0
        {
            if (fabs (d) <= DBL_EPSILON)
            {
                *x1 = -b / 2/a;
                return 1;
            }
            else // d > 0
            {
                *x1 = (-b-sqrt(d)) / 2/a;
                *x2 = (-b+sqrt(d)) / 2/a;
                return 2;
            }
        }
    }
}
